package org.test.device;

import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Slf4j
@EnableAsync
@SpringBootApplication
@MapperScan("org.test.device.mapper")
public class DeviceApplication {

    public static void main(String[] args) {
        try {
            SpringApplication.run(DeviceApplication.class, args);
            log.info("[DEVICE]正在运行中.....（づ￣3￣）づ╭❤～");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Bean
    @Primary
    public TaskExecutor primaryTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //获取CPU核心数
        int cpuCoreNum = Runtime.getRuntime().availableProcessors();
        //动态设置参数
        executor.setCorePoolSize(cpuCoreNum * 2);
        executor.setMaxPoolSize(executor.getCorePoolSize() +cpuCoreNum);
        executor.setQueueCapacity(800);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("Primary-Task-Executor-");
        // 自定义线程工厂，记录线程创建日志
        executor.setThreadFactory(runnable -> {
            Thread thread = new Thread(runnable);
            thread.setName(executor.getThreadNamePrefix() + thread.getId());
            thread.setUncaughtExceptionHandler((t, e) ->
                    log.error("[primaryTaskExecutor]线程[{}]执行任务时发生未捕获异常", t.getName(), e)
            );
            log.info("[primaryTaskExecutor]创建新线程: {}", thread.getName());
            return thread;
        });
        executor.setRejectedExecutionHandler((r, executor1) -> {
            log.error("[primaryTaskExecutor]任务被拒绝！活跃线程数：{}，队列已用容量：{}，队列总容量：{}",
                    executor1.getActiveCount(),
                    executor.getQueueSize(), // 用当前executor实例获取队列已用容量
                    executor.getQueueCapacity());
            //重试逻辑（如延时100ms重试1次）
            try {
                Thread.sleep(100);
                executor.submit(r);
            } catch (Exception e) {
                log.error("[primaryTaskExecutor]重试失败", e);
            }
        });
        executor.initialize();
        // 记录线程池初始化信息
        log.info("[primaryTaskExecutor]线程池初始化完成 - 核心线程数: {}, 最大线程数: {}, 队列容量: {}",
                executor.getCorePoolSize(),
                executor.getMaxPoolSize(),
                executor.getQueueCapacity());
        return executor;
    }
}
